<!DOCTYPE html>
<html>

  <head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>
    我的 jekyll 博客所使用的小工具
    </title>
  <link type="application/atom+xml" rel="alternate" href="/feed.xml" title="虚实" />
  
  <style>
  table{
    border-left:1px solid #000000;border-top:1px solid #000000;
    width: 100%;
    word-wrap:break-word; word-break:break-all;
  }
  table th{
  text-align:center;
  }
  table th,td{
    border-right:1px solid #000000;border-bottom:1px solid #000000;
  }
  </style>

  <meta name="description" content="今天刚刚回到学校，折腾了这么久，终于可以停下来慢慢看书找工作了。">
  <link rel="stylesheet" href="/css/main.css">
  <link rel="stylesheet" href="/css/toc.css">
  <link rel="canonical" href="/2016/02/18/%E6%88%91%E7%9A%84jekyll%E5%8D%9A%E5%AE%A2%E6%89%80%E4%BD%BF%E7%94%A8%E7%9A%84%E5%B0%8F%E5%B7%A5%E5%85%B7/">
  <link rel="alternate" type="application/rss+xml" title="虚实" href="/feed.xml" />
  <link rel="stylesheet" href="/css/highlight.min.css">
  <link href="//cdn.staticfile.org/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet"media="all">
</head>


  <body>

    <header class="site-header">

  <div class="wrapper">
    <div>
      <a class="site-title" href="/">虚实</a>
      <div class="site-pages">
		<a class="site-page" href="/archive/">归档</a>
		<a class="site-page" href="/categories/">分类</a>
		<a class="site-page" href="/about/">关于</a>
		<a class="site-page" href="/friend-links/">友情链接</a>
        <a class="site-page" href="/recommends/">推荐</a>
      </div>
      <p class="site-sub-title">记录下折腾和学习的过程</p>
    </div>

  </div>

</header>


    <div class="page-content">
      <div class="wrapper">
        <div class="post">

  <header class="post-header">
    <h1 class="post-title">我的 jekyll 博客所使用的小工具</h1>
    <p class="post-meta">Feb 18, 2016 • admin</p>

	<p class="post-meta"> categories :   <a href="/categories/#杂货"> 杂货 </a>  </p>
    <div id="show_qrcode">
        <a>扫描二维码</a>
        <div id="qrcode" style="display:none;position:absolute;z-index:1"></div>
    </div>
  </header>
  <div class="nav">
      <div id="toc" class="toc"></div>
  </div>
  <article class="post-content">
    <p>今天刚刚回到学校，折腾了这么久，终于可以停下来慢慢看书找工作了。</p>

<p>很久没有更新技术相关的内容了，偶尔还是得更新一下的，不过这篇也不怎么能算技术相关。</p>

<p>使用 Github Page + Jekyll 的方式写博客一段时间了，分享下为方便写博客自己造的轮子。</p>

<p>首先是编辑，Jekyll默认使用 Markdown 来生成博客内容。支持 Markdown 的编辑器其实很多，我还是继续使用心爱的 Emacs。markdown-mode 使用起来还是凑合的，只是默认的键位和我的 buffer 管理快捷键冲突了，不过只用简单的在配置文件里面配置下就好了。</p>

<p>我使用了 tabbar-mode 来管理 Emacs 的 buffer，tabbar-mode 使用如下配置</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(global-set-key (kbd "&lt;M-up&gt;") 'tabbar-backward-group)

(global-set-key (kbd "&lt;M-down&gt;") 'tabbar-forward-group)

(global-set-key (kbd "&lt;M-left&gt;") 'tabbar-backward-tab)

(global-set-key (kbd "&lt;M-right&gt;") 'tabbar-forward-tab)
</code></pre></div></div>

<p>简单的做法只用在 markdown-mode 写 hook 禁止它覆盖这几个快捷键即可，当然你要继续使用 markdown-mode 的这几个功能可以给其绑定其他的快捷键，我个人不怎么使用就没继续配置了。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(defun my-markdown-config ()
  ;unbind tabbar keys
  (define-key markdown-mode-map (kbd "M-&lt;up&gt;") nil)
  (define-key markdown-mode-map (kbd "M-&lt;down&gt;") nil)
  (define-key markdown-mode-map (kbd "M-&lt;left&gt;") nil)
  (define-key markdown-mode-map (kbd "M-&lt;right&gt;") nil))
 
(add-hook 'markdown-mode-hook 'my-markdown-config)
</code></pre></div></div>

<p>为了在没有Emacs编辑器的时候也能方便的写，也顺便练下手，做了个简单的 <a href="http://woodrat.xyz/simple-markdown-editor/">Markdown 在线编辑器</a>。这个在上一篇博客中已经介绍过了，就不赘述了。这几天把左边的编辑框行号问题给修正了，导出功能也在开发中。</p>

<p>当然也可以选择使用 Atom 或者直接使用为知笔记编写。</p>

<p>Jekyll 文章默认放在项目文件夹的 <code class="language-plaintext highlighter-rouge">_post</code> 文件夹中，文章文件上部分两个 <code class="language-plaintext highlighter-rouge">---</code> 中间是文章的附加信息，可以看作配置信息，以 yaml 的格式书写。重要的几项为 <code class="language-plaintext highlighter-rouge">title</code> <code class="language-plaintext highlighter-rouge">permalink</code> <code class="language-plaintext highlighter-rouge">categories</code>。</p>

<p><code class="language-plaintext highlighter-rouge">title</code> 为标题，自不用多说。<code class="language-plaintext highlighter-rouge">permalink</code> 关系到文章显示的url，可以按日期或者分类为前缀，或者直接使用文件名，不过需要url编码一下，<code class="language-plaintext highlighter-rouge">categories</code> 则代表文章的分类，这里倒问题不大。</p>

<p>同时 Jekyll 要求文章的文件名按照 <code class="language-plaintext highlighter-rouge">YEAR-MONTH-DAY-title.MARKUP</code> 的格式组织。</p>

<p>了解了这些信息后，便可以用 Python 很简单的写出制定标题和分类来自动生成文章的小脚本了，<a href="https://github.com/Mithrilwoodrat/Mithrilwoodrat.github.io/blob/master/gen_post.py">gen_post.py</a>，不过为了方便起见，我并未使用 yaml 的库来生成文件，而是直接用拼接字符串的方式，毕竟只有那么固定几行，没有太大的必要。</p>

<p>虽然写的很简陋不过还是可以将就用一下的 : )</p>

<pre><code class="language-Python">#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import time
import sys
import os
from urllib import quote
from optparse import OptionParser


_base_path = os.path.abspath(os.path.dirname(__file__))
date = time.strftime("%Y-%m-%d") # 文件名按 Jekyll 要求为 YEAR-MONTH-DAY-title.MARKUP
link_path = time.strftime("/%Y/%m/%d/") # url 按 /年/月/日/标题 的方式组织
_post_path =  os.path.join(_base_path, "_posts") # 生成目录为主目录下的 _post 目录


def gen_post(title, category="默认"):
    content = "---\n"
    content += "title: "+ title + "\n"
    content += "author: admin\n"
    content += "layout: post\n"
    # 这里需要注意 url 中标题需要 urlencode 一下
    content += "permalink: " + link_path + quote(title) +'/' + "\n" 
    content += "categories:\n"
    if category:
        content += "  - " + category + "\n" 
    content += "---"
    title = title.replace(' ', '-') # 生成文件名时自动将空格转换为 -
    filename = date + "-" + title + ".md"
    try :
        filepath = os.path.join(_post_path,filename)
        if os.path.isfile(filepath):
            print "file exist"
            return
        post = open(filepath, "w+")
        post.write(content)
        post.close()
        print "create", filename, "success!"
    except Exception as err:
        print err

if __name__ == "__main__":
    parser = OptionParser()
    # 接受标题和分类两个参数，其中分类可以不填，默认为“默认”分类，你也可以按自己情况修改
    parser.add_option("-t", dest="title", help="post title")
    parser.add_option("-c", dest="category", help="post category")
    (options, args) = parser.parse_args()
    if options.title:
        if options.category:
            gen_post(options.title, options.category)
        else:
            gen_post(options.title)
</code></pre>

<p>文章生成好之后将编辑好的内容复制进去就好，当然先生成再用 Emacs 打开编写也是没有问题的。</p>

<p>编写完成后可以使用 <code class="language-plaintext highlighter-rouge">jekyll s</code> 查看效果。</p>

<p>顺带一提，Jekyll 默认的 Markdown 引擎 Kramdown 使用 ~~~ 来标识代码块，和一般大家所熟悉的使用 ``` 的方法不相同，但是根据这个 <a href="https://github.com/jekyll/jekyll/issues/3724">issue</a>，Jekyll 将在 3.1 版本后支持使用 ``` 的方式。</p>

<p>ps: 写的时候豆瓣电台正好随机到 Fly Me to the Moon，good night!</p>

  </article>

</div>
<div id="disqus_thread"></div>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES * * */
    var disqus_shortname = 'yoursoulismine';
    
    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES * * */
    var disqus_shortname = 'yoursoulismine';
    
    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function () {
        var s = document.createElement('script'); s.async = true;
        s.type = 'text/javascript';
        s.src = '//' + disqus_shortname + '.disqus.com/count.js';
        (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
    }());
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://flowchart.js.org/flowchart-latest.js"></script>
<script src="/js/highlight.min.js"></script>
<script src="/js/toc.js"></script>
<script src="/js/qrcode.min.js"></script>
<script>
if (!String.prototype.format) {
    String.prototype.format = function() {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function(match, number) { 
            return typeof args[number] != 'undefined'
                ? args[number]
                : match
            ;
        });
    };
}

$('pre code').each(function(i, block) {
    hljs.highlightBlock(block);
});

$('.language-flow').each(function(i, block) {
    console.log(block);
    code = $(this).text();
    diagram = flowchart.parse(code);
    canvas_id = 'flow'+ i;
    console.log(canvas_id);
    temp = "<div id='{0}'> </div>".format(canvas_id);
    console.log(temp);
    $(this).html(temp);
    diagram.drawSVG(canvas_id, {
        'x': 0,
        'y': 0,
        'line-width': 3,
        'line-length': 50,
        'text-margin': 10,
        'font-size': 14,
    });	
});

$('#toc').toc({
    noBackToTopLinks: true,
    listType: 'ul',
    title: 'TOC',
});

var url = location.href;
console.log(url);
var qrcode = new QRCode("qrcode", {
    text: url,
    width: 128,
    height: 128,
    colorDark : "#000000",
    colorLight : "#ffffff",
    correctLevel : QRCode.CorrectLevel.H
});

$(document).ready(function () {
    $('#show_qrcode').on('mouseenter', function () {
        $('#qrcode').show();
        $(this).css({
            "text-decoration": "underline"
        });
    }).on('mouseleave', function () {
        $('#qrcode').hide();
        $(this).css({
            "text-decoration": ''
        });
    });;
});
</script>

      </div>
    </div>

    <footer class="site-footer">

  <div class="wrapper">


    <div class="footer-col-wrapper">
      <div class="footer-col  footer-col-1">
        <ul class="contact-list">
	  <li>
          <li><a href="mailto:mithrilwoodrat@gmail.com">mithrilwoodrat@gmail.com</a></li>
        </ul>
      </div>

      <div class="footer-col  footer-col-2">
        <ul class="social-media-list">
          
          <li>
            <a href="https://github.com/Mithrilwoodrat">
              <span class="icon  icon--github">
                <svg viewBox="0 0 16 16">
                  <path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/>
                </svg>
              </span>
              <span class="username">Mithrilwoodrat</span> 
            </a>
          </li>
          
        </ul>
      </div>
  </div>
</footer>

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-66599686-1', 'auto');
  ga('send', 'pageview');

</script>
</body>
</html>
